iT邦幫忙

2024 iThome 鐵人賽

DAY 24
0

前言

我們在昨天教給大家設定Security,這樣設置下,無論哪個API都需要有帳號密碼,而這個帳號密碼由於我們沒有設置,所以是由系統指定一個user,並且給一個密碼讓我們使用。
接下來我們要學更進階一點的功能,就是設定不同的權限,以及給系統一組指定的帳號密碼。
那就讓我們開始吧!

新增userDetailsService

首先,讓我們來在config檔中設定我們的帳號密碼以及權限。Spring Secuirty其實已經有一個class,我們只要呼叫這個class就可以,這個就是UserDatailsService

@Bean

	public UserDetailsService userDetailsService() {



		return new InMemoryUserDetailsManager();

	}

我們可以在這個頁面中宣告我們要的帳號密碼,以及他所有的權限,就可以在網址中設定我要甚麼樣子的權限才能夠取得資料,我們先設定Eric跟admin的資料,設定完成後就會如以下的程式碼。


package net.Eric.accounting.config;




import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.http.HttpMethod;

import org.springframework.security.config.Customizer;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;

import org.springframework.security.core.userdetails.User;

import org.springframework.security.core.userdetails.UserDetails;

import org.springframework.security.core.userdetails.UserDetailsService;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import org.springframework.security.crypto.password.PasswordEncoder;

import org.springframework.security.provisioning.InMemoryUserDetailsManager;

import org.springframework.security.web.SecurityFilterChain;

import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;




import lombok.AllArgsConstructor;




@Configuration

@AllArgsConstructor

public class SpringSecurityConfig {


	@Bean

	SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

		

		http.csrf((csrf) -> csrf.disable())

			.authorizeHttpRequests((authorize)->{

				authorize.anyRequest().authenticated();

			}).httpBasic(Customizer.withDefaults());


		return http.build();

	}

	

	@Bean

	public static PasswordEncoder passwordEncoder() {

		return new BCryptPasswordEncoder();

	}

	

  	@Bean

	public UserDetailsService userDetailsService() {

		UserDetails Eric = User.builder()

				.username("Eric")

				.password(passwordEncoder().encode("123321"))

				.roles("USER")

				.build();

		

		UserDetails admin = User.builder()

				.username("admin")

				.password(passwordEncoder().encode("admin"))

				.roles("ADMIN")

				.build();

		

		return new InMemoryUserDetailsManager(Eric,admin);

	}




}

設置權限分流

接下來,我們要設定那些權限可以使用那些網址,這可以用這個方法

authorize.requestMatchers(HttpMethod.POST,"/api/**").hasRole("ADMIN");

其實很簡單,我們可以指定是哪個HttpMethod,以及是哪個網址,hasRole就如同字面上意義,就是哪個權限可以訪問。
我們先設定Post資料只有admin才有,然後Get的資料是USER跟ADMIN都可以,完成後就會如同以下的程式碼

@Bean

	SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

		

		http.csrf((csrf) -> csrf.disable())

			.authorizeHttpRequests((authorize)->{

				authorize.requestMatchers(HttpMethod.POST,"/api/**").hasRole("ADMIN");

				authorize.requestMatchers(HttpMethod.GET,"/api/**").hasAnyRole("ADMIN","USER");

				

				authorize.anyRequest().authenticated();

			}).httpBasic(Customizer.withDefaults());

		




		return http.build();

	}

接下來我們就要開始測試
首先先測試Post的權限,我們使用剛剛設定的User帳號去新增accounts資料,因為我們權限的設定,USER並沒有權限去新增資料,就會回傳403 forbidden的結果,就如同以下Postman結果
https://ithelp.ithome.com.tw/upload/images/20241003/20152864Zu8l6SLr0s.png
再來,我們使用admin的帳號新增資料,就會出現成功的畫面,並且新增資料進資料庫
https://ithelp.ithome.com.tw/upload/images/20241003/20152864MFX9tfeByL.png

GET方法

再來我們測試Get方法,這個方法是USER跟ADMIN都可以的,所以我們先用USER來測試
https://ithelp.ithome.com.tw/upload/images/20241003/20152864XLgINMG701.png
再來用admin來測試
https://ithelp.ithome.com.tw/upload/images/20241003/20152864RgkICBKMtG.png
到了這裡,大家就成功設置新的帳號密碼,以及不同的腳色權限可以連線到不同的網址的方式,增加了對於網站的安全性保護了!


上一篇
Day30 React前端登入串接與完賽心得
系列文
前後端整合,用Spring boot 與React 開發屬於自己的記帳網頁30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言